package com.ehsunbehravesh.mypasswords;

import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Domain {

  //public static final String connectionUrl = "jdbc:derby:%sdatabase;user=app;password=13621215;";
    /**
     * changing the url to relative do to bug of space in the folder name
     * by ehsun
     */
  public static final String connectionUrl = "jdbc:derby:database;user=app;password=13621215;";
  public static final String driverClassName = "org.apache.derby.jdbc.EmbeddedDriver";
  private static Domain instance = null;
  private long lastConnection;
  private String password;
  
  //<editor-fold defaultstate="collapsed" desc="Constructors & Distructors">
  protected Domain() {
    this.lastConnection = System.currentTimeMillis();
  }

  public static Domain getInstance() {
    if (instance == null) {
      instance = new Domain();
    }
    return instance;
  }
  //</editor-fold>

  //<editor-fold desc="Methods">
  public Connection getDBConnection() {
    Connection dbConnection = null;
    try {
      Class.forName(driverClassName);
      try {
        String url = String.format(connectionUrl, Utils.getPathOfJar());        
        dbConnection = DriverManager.getConnection(url);
        this.lastConnection = System.currentTimeMillis();
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
      }
    } catch (ClassNotFoundException ex) {
      Logger.log(ex.getMessage());
    }
    return dbConnection;
  }

  public String getSetting(String key, String encryptionKey) {
    Connection con = getDBConnection();

    if (con != null) {
      try {
        Statement st = con.createStatement();
        String sql = String.format("SELECT * FROM SETTING WHERE \"KEY\" = '%s'", key);

        ResultSet rs = st.executeQuery(sql);
        if (rs.next()) {
          String value = rs.getString("value");
          if (encryptionKey != null) {
            try {
              value = Utils.decrypt(encryptionKey, value);              
            } catch (Exception ex) {
              Logger.log(ex.getMessage());
            }
          }
          return value;
        } else {
          return null;
        }
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
        return null;
      } finally {
        try {
          con.close();
        } catch (SQLException ex) {
          Logger.log(ex.getMessage());
          return null;
        }
      }
    } else {
      return "";
    }
  }

  public boolean setSetting(String key, String value, String encriptionKey) {
    Connection con = getDBConnection();

    if (con != null) {
      try {
        Statement st = con.createStatement();
        String sql = "";

        if (encriptionKey != null) {
          try {
            value = Utils.encrypt(encriptionKey, value);
          } catch (Exception ex) {
            Logger.log(ex.getMessage());
          }
        }

        if (getSetting(key, null) != null) {
          sql = String.format("UPDATE SETTING SET VALUE = '%s' WHERE \"KEY\" = '%s'", value, key);
        } else {
          sql = String.format("INSERT INTO SETTING (\"KEY\", VALUE) VALUES ('%s', '%s')", key, value);
        }

        return st.executeUpdate(sql) == 1;
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
        return false;
      } finally {
        try {
          con.close();
        } catch (SQLException ex) {
          Logger.log(ex.getMessage());
          return false;
        }
      }
    } else {
      return false;
    }
  }

  public boolean setHashedSetting(String key, String value) throws NoSuchAlgorithmException {
    Connection con = getDBConnection();

    if (con != null) {
      try {
        Statement st = con.createStatement();
        String sql = "";
        
        value = Utils.SHA256(value);

        if (getSetting(key, null) != null) {
          sql = String.format("UPDATE SETTING SET VALUE = '%s' WHERE \"KEY\" = '%s'", value, key);
        } else {
          sql = String.format("INSERT INTO SETTING (\"KEY\", VALUE) VALUES ('%s', '%s')", key, value);
        }

        return st.executeUpdate(sql) == 1;
      } catch (SQLException ex) {
        Logger.log(ex.getMessage());
        return false;
      } finally {
        try {
          con.close();
        } catch (SQLException ex) {
          Logger.log(ex.getMessage());
          return false;
        }
      }
    } else {
      return false;
    }
  }
  
  public int minutesOfLastDBConnection() {
    long now = System.currentTimeMillis();
    long difference = now - lastConnection;
    int minutes = Math.round(difference / 60000);
    return minutes;
  }

  public float getMyPasswordsVersion() {
    return (float) 2.92;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }  
    //</editor-fold>
}
